// Author: Domien Nowicki

#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QStyleOption>

#include "MapLandItem.h"
#include "MapProvinceItem.h"
#include "MapWidget.h"

using std::min;
using std::max;


MapLandItem::MapLandItem(MapWidget *mapView, const std::string& name): map(mapView), Land(name)
{
	// Set Z value of the land to below a province
	setZValue(LANDZ);
}

MapLandItem::~MapLandItem()
{
}

MapLandItem::MapLandItem(const MapLandItem& rhs): map(rhs.map), Land(rhs.GetName())
{
	// Set Z value of the land to below a province
	setZValue(LANDZ);
	Copy(rhs);
}

MapLandItem::MapLandItem(MapWidget *mapView, const Land& rhs): map(mapView), Land(rhs.GetName())
{
	// Set Z value of the land to below a province
	setZValue(LANDZ);
	Copy(rhs);
}

QRectF MapLandItem::boundingRect() const
{
	// Return the bounding rectangle of this item
	int xmin = 0;
	int xmax = 0;
	int ymin = 0;
	int ymax = 0;

	std::list<Province*>::const_iterator provinceIt;

	bool gotFirstProvince = false;

	for(provinceIt = provinces.begin(); provinceIt != provinces.end(); ++provinceIt)
	{
		const MapProvinceItem* province = (const MapProvinceItem*)*provinceIt;

		// Bounding rectangle is the total bounding rectangle of all provinces combined
		const QRectF bounds = province->boundingRect();
		int x0 = bounds.x();
		int x1 = x0 + bounds.width();
		int y0 = bounds.y();
		int y1 = y0 + bounds.height();

		
		// Initialize step
		if (!gotFirstProvince)
		{
			gotFirstProvince = true;
			xmin = x0;
			xmax = x1;
			ymin = y0;
			ymax = y1;
		}
		else
		{
			xmin = min(xmin, x0);
			xmax = max(xmax, x1);
			ymin = min(ymin, y0);
			ymax = max(ymax, y1);
		}
	}

	return QRectF(xmin, ymin, (xmax-xmin), (ymax-ymin));
}

QPainterPath MapLandItem::shape() const
{
	// Return the shape of this item
	QPainterPath temp;
	std::list<Province*>::const_iterator it;

	for(it = provinces.begin(); it != provinces.end(); ++it)
	{
		const MapProvinceItem *province = (MapProvinceItem*)*it;

		// Combine shapes of each province's polygon
		temp.addPath(province->shape());
	}
	
	return temp;
}

void MapLandItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	// Draw land line here
}

void MapLandItem::AddToScene(QGraphicsScene *newScene, QGraphicsItem *item)
{
	// Add item to scene, or add self to scene if item is null
	if (newScene)
	{
		if (0 == item)
			item = this;

		// Add item to the scene
		newScene->addItem(item);

		// Tell listeners that their parent was added to a scene
		emit parentAddedToScene(newScene);
	}
}

Province* MapLandItem::InsertProvince(MapProvinceItem* item)
{
	// Connect the clicked province signal so we can propagate it to the map widget
	QObject::connect(item, SIGNAL(clickedProvince(Province*)), this, SLOT(slotClickedProvince(Province*)));
	// Connect the scene signal so that childs can add themself to the scene
	QObject::connect(this, SIGNAL(parentAddedToScene(QGraphicsScene*)), item, SLOT(AddToScene(QGraphicsScene*)));
	// Connect the cursor signal so that childs can update their cursors
	QObject::connect(this, SIGNAL(cursorChanged(const QCursor&)), item, SLOT(SetCursor(const QCursor&)));

	// Add the item to the scene
	AddToScene(scene(), item);

	// Insert the province
	return Land::InsertProvince( item );
}

Province* MapLandItem::InsertNewProvince(const std::string& name)
{
	return InsertProvince( new MapProvinceItem(map, name) );
}

Province* MapLandItem::InsertNewProvince(const Province& rhs)
{
	return InsertProvince( new MapProvinceItem(map, rhs) );
}

void MapLandItem::slotClickedProvince(Province *province)
{
	// Notify listeners that a province was clicked
	emit clickedProvince(this, province);
}

void MapLandItem::SetCursor(const QCursor& cursor)
{
	// Notify listeners that the cursor was changed
	emit cursorChanged(cursor);
}
